package io.pumelo.wxjump.anserine;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.sun.media.sound.SoftTuning;
import com.xiaoleilu.hutool.http.Header;
import com.xiaoleilu.hutool.http.HtmlUtil;
import com.xiaoleilu.hutool.http.HttpRequest;
import com.xiaoleilu.hutool.http.HttpUtil;
import com.xiaoleilu.hutool.io.FileUtil;
import com.xiaoleilu.hutool.util.CharsetUtil;
import com.xiaoleilu.hutool.util.ReUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sun.org.apache.xml.internal.security.utils.Base64;


public class OCRDemoForHttp {

    static Logger logger = LoggerFactory.getLogger(OCRDemoForHttp.class);
    private static String ask1 = "https://www.baidu.com/s?ie=UTF-8&wd=";
    private static String ask2 = "https://zhidao.baidu.com/search?lm=0&rn=10&pn=0&fr=search&ie=gbk&word=";

    public static void main(String[] args) throws Exception {
        List<String> re = getTipBypic(ask2, "2db17fab0e757900", "Wxt2Br0OxP9Rkq6zgBYYK6BUJrUHULXl", "d://3.png");
        for (String s : re) {
            System.out.println(s);
        }
    }

    private static List<String> getTipBypic(String ask2, String appkey, String appSecrite, String picPath) throws Exception {
        Map map = new HashMap<>();
        String url = "http://openapi.youdao.com/ocrapi";
        String appKey = appkey;
        String detectType = "10011";
        String imageType = "1";
        String langType = "zh-en";
        String docType = "json";
        String salt = String.valueOf(System.currentTimeMillis());
        String img = getImageStr(picPath);

        map.put("appKey", appKey);
        map.put("img", img);
        map.put("detectType", detectType);
        map.put("imageType", imageType);
        map.put("langType", langType);
        map.put("salt", salt);
        map.put("docType", docType);
        String sign = md5(appKey + img + salt + appSecrite);
        map.put("sign", sign);
        String result = requestOCRForHttp(url, map);
        // System.out.println(result);
        // regions lines words

        JSONObject a = JSONObject.fromObject(result);
        JSONObject b = a.getJSONObject("Result");

        JSONArray c = b.getJSONArray("regions");

        JSONObject d = (JSONObject) c.get(0);

        JSONArray e = d.getJSONArray("lines");

        StringBuffer sb = new StringBuffer();
        for (int kk = 0; kk < e.size(); kk++) {
            JSONObject f = (JSONObject) e.get(kk);
            JSONArray g = f.getJSONArray("words");
            for (int kkk = 0; kkk < g.size(); kkk++) {
                sb.append(((JSONObject) g.get(kkk)).getString("text"));
            }
        }
        String ask = sb.toString();
        System.out.println("解析到的问题:" + ask);

        List<String> links = getanswer(ask2, sb.toString());
        System.out.println("解析后数量:" + links.size());


        List<String> allre = new ArrayList<>();
        int j = 1;
        for (String li : links) {
            if (j - 1 == 0) {
                j++;
                continue;
            }
            if (j - 7 == 0) {
                return allre;
            }
            System.out.println("访问:" + li);
            HttpRequest request = HttpRequest.get(dealurl(li)).charset(CharsetUtil.GBK);

            String an = request.header(Header.CONTENT_TYPE.toString(), "application/x-www-form-urlencoded;charset=GBK").
                    setFollowRedirects(true).execute().body();

            List<String> titles = ReUtil.findAll("<span class=\"answer-title h2 grid\">(.*?)<div class=\"quality-content-view-more mb-15\">", an, 1);
            if (null != titles && titles.size() > 0) {
                String s = io.pumelo.wxjump.anserine.HtmlUtil.delHTMLTag(titles.get(0));
                s = s.replaceAll("最佳答案", "");
                allre.add(s);
            }
            j++;
        }

        return allre;
        //FileUtil.appendLines(titles, "d://a.html", "utf8");
    }

    private static List<String> getanswer(String ask2, String s) {
        String s2 = null;
        try {
            s2 = URLEncoder.encode(s, "utf8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // System.out.println(s2);
        String con = HttpUtil.get(ask2 + s2);
        //FileUtil.writeString(con, "d://a.html", "utf8");

        List<String> liks = parseBaiduSearchLinks(con);
        return liks;
    }

    private static String dealurl(String url) {
        return url.replaceAll("\"", "");
    }


    /**
     * 解析百度搜索出的页面提取链接
     *
     * @param content
     * @return
     */
    public static List<String> parseBaiduSearchLinks(String content) {
        System.out.println(content);
        Pattern regBaidu = Pattern.compile("https://zhidao.baidu.com/question/(.*)");
        //Pattern regBaidu2 = Pattern.compile("\"https://www\\.baidu\\.com/link\\?url=(.*)\"");
        List<String> rst = new ArrayList<String>();
        Matcher mt = regBaidu.matcher(content);
        //Matcher mt2 = regBaidu2.matcher(content);
        while (mt.find()) {
            // System.out.println("找到了一个连接" + mt.group());
            Link tlink = new Link();
            String a = mt.group();
            a = a.replaceFirst("\"", "");
            a = a.substring(0, a.indexOf("\""));

            if (rst.contains(a)) {
            } else {
                System.out.println(a);
                rst.add(a);
            }

        }
        return rst;
    }

    private static Link initPrimiryLink(String url) {
        Link link = new Link();
        link.setDepth(0);
        link.setParent(null);
        link.setUrl(url);
        return link;
    }

    public static String requestOCRForHttp(String url, Map requestParams) throws Exception {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        /**HttpPost*/
        HttpPost httpPost = new HttpPost(url);
        List params = new ArrayList();
        params.add(new BasicNameValuePair("appKey", (String) requestParams.get("appKey")));
        params.add(new BasicNameValuePair("img", (String) requestParams.get("img")));
        params.add(new BasicNameValuePair("detectType", (String) requestParams.get("detectType")));
        params.add(new BasicNameValuePair("imageType", (String) requestParams.get("imageType")));
        params.add(new BasicNameValuePair("langType", (String) requestParams.get("langType")));
        params.add(new BasicNameValuePair("salt", (String) requestParams.get("salt")));
        params.add(new BasicNameValuePair("sign", (String) requestParams.get("sign")));
        params.add(new BasicNameValuePair("docType", (String) requestParams.get("docType")));
        httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        /**HttpResponse*/
        CloseableHttpResponse httpResponse = httpClient.execute(httpPost);
        try {
            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity, "utf-8");
            EntityUtils.consume(httpEntity);
        } finally {
            try {
                if (httpResponse != null) {
                    httpResponse.close();
                }
            } catch (IOException e) {
                logger.info("## release resouce error ##" + e);
            }
            return result;
        }

    }

    /**
     * 获得图片的Base64编码
     *
     * @param imgFile
     * @return
     */
    public static String getImageStr(String imgFile) {//将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //对字节数组Base64编码
        return Base64.encode(data);//返回Base64编码过的字节数组字符串
    }

    /**
     * 生成32位MD5摘要
     *
     * @param string
     * @return
     */
    public static String md5(String string) {
        if (string == null) {
            return null;
        }
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F'};
        byte[] btInput = string.getBytes();
        try {
            /** 获得MD5摘要算法的 MessageDigest 对象 */
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            /** 使用指定的字节更新摘要 */
            mdInst.update(btInput);
            /** 获得密文 */
            byte[] md = mdInst.digest();
            /** 把密文转换成十六进制的字符串形式 */
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (NoSuchAlgorithmException e) {
            return null;
        }
    }
}